package com.tcoiss.app.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tcoiss.app.domain.TrackService;
import com.tcoiss.app.domain.TrackVo;
import com.tcoiss.app.mapper.TrackServiceMapper;
import com.tcoiss.app.service.ITrackServiceService;
import com.tcoiss.common.core.enums.ErroEnums;
import com.tcoiss.common.core.exception.CustomException;
import com.tcoiss.common.core.utils.SecurityUtils;
import com.tcoiss.common.component.api.model.AddressVo;
import com.tcoiss.common.component.service.ApiHelperService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 轨迹服务配置Service业务层处理
 *
 * @author zw
 * @date 2021-02-21
 */
@Service
public class TrackServiceServiceImpl extends ServiceImpl<TrackServiceMapper, TrackService> implements ITrackServiceService {

    @Autowired
    private ApiHelperService apiHelperService;

    @Override
    public List<TrackService> queryList(TrackService trackService) {
        LambdaQueryWrapper<TrackService> lqw = Wrappers.lambdaQuery();
        if (trackService.getDataLevel() != null){
            lqw.le(TrackService::getDataLevel ,trackService.getDataLevel());
        }
        if(StringUtils.isNotBlank(trackService.getPhone())){
            lqw.eq(TrackService::getPhone ,trackService.getPhone());
        }
        if(StringUtils.isNotBlank(trackService.getEnterprise())){
            lqw.eq(TrackService::getEnterprise ,trackService.getEnterprise());
        }
        if(StringUtils.isNotBlank(trackService.getGaodeKey())){
            lqw.eq(TrackService::getGaodeKey ,trackService.getGaodeKey());
        }
        return this.list(lqw);
    }

    @Override
    public TrackService getOneByAddrss(AddressVo addressVo) {
        return null;
    }

    public TrackService getOneByKey(String key){
        TrackService trackService = new TrackService();
        trackService.setGaodeKey(key);
        List<TrackService> trackServices = queryList(trackService);
        if(trackServices.size()>1){
            throw new CustomException(ErroEnums.DATAERRO.getCode(),new Object[] {key},"你的key为: " + key +"存在多个相同的key");
        }
        return trackServices.get(0);
    }

    // 更新使用状态
    @Override
    public boolean updateStatus(List<Long> idList, Integer status) {
        if (idList != null & status != null) {
            for (Long id : idList) {
                TrackService ew = getById(id);
                if (ew.getDataLevel() != status) {
                    ew.setDataLevel(status);
                    this.updateById(ew);
                }
            }
            return true;
        }
        return false;
    }


    @Override
    public boolean saveTrackService(TrackService trackService,String apiCode) {
        Map<String,Object> param = new HashMap<>();
        param.put("key",trackService.getGaodeKey());
        param.put("name",trackService.getFwName());
        param.put("desc",trackService.getServiceDesc());
        Map<String,Object> resultMap = apiHelperService.executeApi(apiCode,param);
        if(resultMap == null){
            //throw new ApiException("code404",new Object[] { apiCode },"http请求连接异常");
            throw new CustomException(ErroEnums.APIERRO.getCode(),new Object[]{apiCode},"http请求连接异常");
        }
        if(Integer.valueOf(resultMap.get("errcode").toString())==10000){//成功
            String sid = JSON.parseObject(resultMap.get("data").toString()).get("sid").toString();
            trackService.setServiceId(sid);
            trackService.setCreatorId(SecurityUtils.getUserId());
            trackService.setCreatorName(SecurityUtils.getUsername());
            return this.save(trackService) ;
        }else{//errmsg
            throw new CustomException(ErroEnums.APIERRO.getCode(),new Object[]{apiCode,resultMap.get("errcode").toString()},
                    ErroEnums.APIERRO.getInfo() + "接口调用异常："+resultMap.get("errdetail").toString());
        }
    }

    @Override
    public String importTable(List<TrackVo> vos) {
        if (com.tcoiss.common.core.utils.StringUtils.isNull(vos) || vos.size() == 0) {
            throw new CustomException(ErroEnums.DATAERRO.getCode(),new Object[]{},"导入数据不能为空！");
        }
        List<Integer> errorCount = VosIsEmpty(vos);
        StringBuilder successMsg = new StringBuilder();
        List<TrackService> columns = new ArrayList<>();
        int lastPriority = getPriorityLast();
        for (int i = 0; i < vos.size(); i++) {
            TrackVo vo = vos.get(i);
            this.checkKey(vos.get(i).getGaodeKey());
            TrackService column = new TrackService();
            column.setCreatorId(SecurityUtils.getUserId());
            column.setCreatorName(SecurityUtils.getUsername());
            column.setPriority(lastPriority++);
            column.setEnterprise(vo.getEnterprise());
            column.setDeveloper(vo.getDeveloper());
            column.setPhone(isPhone(vo.getPhone(),i));
            column.setPassword(vo.getPassword());
            column.setGaodeKey(vo.getGaodeKey());
            columns.add(column);
        }
        if (this.saveBatch(columns)) {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + columns.size() + " 条,被删数据列"+ errorCount);
        } else {
            throw new CustomException(ErroEnums.DATAERRO.getCode(), new Object[]{}, ErroEnums.DATAERRO.getInfo() + "保存列数据异常");
        }
        return successMsg.toString();
    }

    /** 判断电话号码格式是否正确 */
    private String isPhone(String phone , Integer count){
        String regex = "0\\d{2,3}[-]?\\d{7,8}|0\\d{2,3}\\s?\\d{7,8}|1[0-9]\\d{9}|15[1089]\\d{8}";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(phone);
        if(matcher.matches()) {
            return phone;
        } else {
            throw new CustomException(ErroEnums.SYSERRO.getCode(), new String[]{phone}, ErroEnums.SYSERRO.getInfo() + "第"+ ++count +"列电话号码无效或格式不正确!");
        }
    }

    /** 判断有无空字段 */
    private List<Integer> VosIsEmpty(List<TrackVo> vos) {
        List<Integer> counts = new LinkedList<>();
        Integer count = null;
        for (int i = 0; i < vos.size(); i++) {
            if (com.tcoiss.common.core.utils.StringUtils.isEmpty(vos.get(i).getEnterprise())) {
                if (count == null) count = i+1;
                counts.add(count++);
                vos.remove(i--);
            }
        }
        return counts;
    }

    /** 检测key值是否存在 */
    private void checkKey(String key) {
        LambdaQueryWrapper<TrackService> lqw = Wrappers.lambdaQuery();
        if (com.tcoiss.common.core.utils.StringUtils.isNotBlank(key)) {
            lqw.eq(TrackService::getGaodeKey, key);
        }
        if (this.list(lqw).size() > 0) {
            throw new CustomException(ErroEnums.DATAERRO.getCode(), new String[]{key}, ErroEnums.DATAERRO.getInfo() + "保存失败，key已经存在");
        }
    }

    /** 查询可用的key */
    public TrackService getUsableKey(){
        LambdaQueryWrapper<TrackService> lqw = Wrappers.lambdaQuery();
        lqw.orderByAsc(TrackService::getPriority);
        lqw.lt(TrackService::getFenceNum,10);
        lqw.eq(TrackService::getDataLevel,1);
        List<TrackService> ts = this.list(lqw);
        if(!ts.isEmpty()){
            /*String key = ts.get(0).getGaodeKey();
            if(StringUtils.isNotBlank(key)){
                return ts;
            }*/
            return ts.get(0);
        }
        return null;
    }

    /** 获取默认的key */
    public TrackService getDefaultKey(){
        LambdaQueryWrapper<TrackService> lqw = Wrappers.lambdaQuery();
        lqw.orderByAsc(TrackService::getPriority);
        List<TrackService> ts = this.list(lqw);
        if(!ts.isEmpty()){
            return ts.get(0);
        }
        return null;
    }

    /** 围栏数量自增 */
    @Override
    public boolean addFenceNum(TrackService trackService,int num) {
        if(trackService.getFenceNum()==0&&num<0){
            throw new CustomException(ErroEnums.SYSERRO.getCode(),new Object[]{},
                    ErroEnums.SYSERRO.getInfo() + "围栏数量异常");
        }
        trackService.setFenceNum(trackService.getFenceNum()+num);
        return this.updateById(trackService);
    }

    /** 自增优先级 */
    @Override
    public Integer getPriorityLast(){
        TrackService ts = this.getOne(new QueryWrapper<TrackService>().orderByDesc("priority").last("limit 1"));
        return ts.getPriority()+1;
    }

    @Override
    public List<Map<String, Object>> getDistrictInfo(TrackService track, String apiCode) {
        Map<String,Object> requestMap = new HashMap<>();
        requestMap.put("keywords",track.getServiceCity());
        requestMap.put("subdistrict",2);
        requestMap.put("extensions","base");
        requestMap.put("key",track.getGaodeKey());
        Map resultMap = apiHelperService.executeApi(apiCode,requestMap);
        if(resultMap == null){
            throw new CustomException(ErroEnums.APIERRO.getCode(),new String[]{apiCode},ErroEnums.APIERRO.getInfo() + "http请求连接异常");
        }else{
            if(Integer.valueOf(resultMap.get("infocode").toString())==10000) {//创建成功
                //更新坐标数据
                List<Object> citys = (List<Object>) resultMap.get("districts");
                Map<String,Object> city = (Map<String, Object>) citys.get(0);
                List<Map<String,Object>> districts = (List<Map<String,Object>>) city.get("districts");
                return districts;
            }else{
                throw new CustomException(ErroEnums.APIERRO.getCode(), new String[]{apiCode,resultMap.get("infocode").toString()},
                        ErroEnums.APIERRO.getInfo() + "接口调用异常："+resultMap.get("info").toString());
            }
        }
    }

}
